package com.yhb.channel.model;

import com.yhb.channel.PayChannel;
import com.yhb.channel.utils.CardSupportiveVerifier;
import com.yhb.channel.utils.ChannelDateUtil;
import lombok.*;
import lombok.extern.log4j.Log4j;
import org.jetbrains.annotations.NotNull;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;

/**
 * 通道信息model
 *
 * 对于一家通道的选择 首先是时间上可用 然后是银行受支持
 * 对于满足以上的条件
 * 按
 * 1. 成本费率之和
 * 2. 对于1相同的情况 按偏好数值排序
 */
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Log4j
public class SubChannelInfo implements Comparable<SubChannelInfo> {

    public static final int FIVE_MINUTES = 5 * 60;

    private String channelName;
    private String channelType;

    private Calendar payStartTime; // 交易支持时间 开始 格式: HH:mm
    private Calendar payEndTime; // 交易支持时间 结束 格式: HH:mm
    private Calendar remitStartTime; // 出款支持时间 开始 格式: HH:mm
    private Calendar remitEndTime; // 出款支持时间 结束 格式: HH:mm

    private BigDecimal limitPerFlow; // 单笔限额 小于等于0时不考虑 为null时不考虑

    private int creditCostRate; // 信用卡成本费率(%)
    private int debitCostRate; // 储蓄卡成本费率(%)

    private Integer degreeOfPreference; // 偏好程度 越大越优先

    private String[] supportPayBankNames; // 支持的支付银行名列表
    private String[] supportRemitBankNames; // 支持的代付银行名列表

    private CardSupportiveVerifier payCardVerifier; // 校验支付卡是不是支持
    private CardSupportiveVerifier remitCardVerifier; // 校验代付卡是不是支持

    private PayChannel payChannel; // 对应的支付通道实例

    private boolean supportDebitCardAsPayCard; // 是否支持储蓄卡作为支付卡

    private boolean noNeedQueryBalance; // 查全部通道余额时，跳过此通道

    private boolean close; // 通道开关 决定进不进快收轮询

    @Override
    public int compareTo(@NotNull SubChannelInfo another) {
        Integer costOfThis = this.creditCostRate + this.debitCostRate;
        Integer costOfThat = another.getCreditCostRate() + another.getDebitCostRate();
        int diff = costOfThis.compareTo(costOfThat);
        if (diff != 0) {
            return diff;
        }
        return another.getDegreeOfPreference().compareTo(this.getDegreeOfPreference());
    }

    /**
     * 判断此时能不能用这个通道
     * 5分钟之后还能使用才算可以使用
     * @return 是否能使用
     */
    public boolean isNowOk() {
        var afterFiveMinutes = ChannelDateUtil.getAfterDate(FIVE_MINUTES);
        // 重置为2333年1月1号去对比
        afterFiveMinutes.set(2333, Calendar.JANUARY, 1);
        boolean payTimeOk = ChannelDateUtil.isBelongToPeriod(afterFiveMinutes, payStartTime, payEndTime);
        boolean remitTimeOk  = ChannelDateUtil.isBelongToPeriod(afterFiveMinutes, remitStartTime, remitEndTime);
        log.info("channel support check isNowOk:" + getChannelType()
                + " payStartTime: " + payStartTime + "-"
                + " payEndTime: " + payEndTime + "-"
                + " remitStartTime: " + remitStartTime + "-"
                + " remitEndTime: " + remitEndTime + "-"
                + " afterFiveMinutes: " + afterFiveMinutes + "-"
                + "->" + payTimeOk + "," + remitTimeOk);
        return payTimeOk && remitTimeOk;
    }

    /**
     * 判断银行卡能不能用这个通道
     * 两张卡都可以使用才算可以使用
     * @return 是否能使用
     */
    public boolean isBanksOk(@NotNull IBankCard payCard, @NotNull IBankCard remitCard) {
        String payBankName = payCard.getBankName();
        String remitBankName = remitCard.getBankName();
        boolean supported = payCardVerifier.support(payCard) && remitCardVerifier.support(remitCard);
        log.info("channel support check isBanksOk:" + getChannelType()
                    + " card: " + payCard.getNumber() + "-" + payBankName
                    + "->" + remitCard.getNumber() + "-" + remitBankName + " :" + supported);
        return supported;
    }

    /**
     * 判断单笔限额是否满足
     * @param amount 单笔限额
     * @return 是否满足
     */
    public boolean isAmountOk(@NotNull BigDecimal amount) {
        if (limitPerFlow == null || BigDecimal.ZERO.compareTo(limitPerFlow) >= 0) {  // 0大于等于限额 或者限额不存在
            log.info("channel support check isAmountOk:" + getChannelType()
                    + "amount: " + amount
                    + "->" + true
            );
            return true;
        }
        var result = amount.compareTo(limitPerFlow) <= 0;
        log.info("channel support check isAmountOk:" + getChannelType()
                + "amount: " + amount
                + "limitPerFlow: " + limitPerFlow
                + "->" + result
        );
        return result;
    }

    /**
     * 支付卡校验
     * 如果是信用卡 进入下一道校验 当卡类型为储蓄卡 需要看通道的supportDebitCardAsPayCard 如果false直接干掉
     * @param payCard 支付卡
     * @return 是否Ok
     */
    public boolean isPayCardOk(@NotNull IBankCard payCard) {
        return this.supportDebitCardAsPayCard || payCard.getCardType() == 1;
    }
}
